package com.shun.upms.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shun.common.R;
import com.shun.common.RC;
import com.shun.common.utils.ShunCommonUtils;
import com.shun.upms.common.UpmsConstant;
import com.shun.upms.dto.SysAdminUserDto;
import com.shun.upms.dto.SysAdminUserQueryDto;
import com.shun.upms.mapper.SysAdminMenuMapper;
import com.shun.upms.mapper.SysAdminRoleMapper;
import com.shun.upms.mapper.SysAdminUserMapper;
import com.shun.upms.service.ISysAdminUserService;
import com.shun.upms.vo.SysAdminMenu;
import com.shun.upms.vo.SysAdminRole;
import com.shun.upms.vo.SysAdminUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 管理人员表 服务实现类
 * </p>
 *
 * @author clever
 * @since 2021-09-27
 */
@Slf4j
@Service
public class SysAdminUserServiceImpl extends ServiceImpl<SysAdminUserMapper, SysAdminUser> implements ISysAdminUserService {

    @Autowired
    private SysAdminUserMapper userMapper;

    @Autowired
    private SysAdminMenuMapper menuMapper;

    @Autowired
    private SysAdminRoleMapper roleMapper;

    @Override
    public R getUserIdByAccAndPwd(String acct, String pwd) {
        SysAdminUser adminUser = new LambdaQueryChainWrapper<SysAdminUser>(this.baseMapper).
                eq(SysAdminUser::getSauAccount, acct).one();
        if(null != adminUser){
            String salt = adminUser.getSauSalt();
            //密码通过MD5+SALT进行加密不可逆
            String enPasswd = SaSecureUtil.md5BySalt(pwd,salt);
            if(adminUser.getSauPassword().equals(enPasswd)){
                return R.suc(adminUser.getSauId());
            }
        }
        return RC.SYSTEM_FAIL_LOGIN.toR();
    }

    @Override
    public R addAdminUser(SysAdminUserDto dto) {
        log.debug("SysAdminUserDto:{}",dto);
        SysAdminUser sysAdminUser = ShunCommonUtils.beanMap(dto,SysAdminUser.class);
        sysAdminUser.setSauId(IdUtil.objectId());
        String salt = RandomUtil.randomNumbers(16);
        sysAdminUser.setSauSalt(salt);
        sysAdminUser.setSauPassword(SaSecureUtil.md5BySalt(UpmsConstant.DEFAULT_PASSWORD,salt));
        StpUtil.getLoginIdAsString();
        sysAdminUser.setUpdateUser(StpUtil.getLoginIdAsString());
        sysAdminUser.setCreateUser(StpUtil.getLoginIdAsString());
        for(String roleId:dto.getRoles()){
            int result = roleMapper.addRolesAndUser(sysAdminUser.getSauId(),roleId);
            if(result <= 0){
                return RC.UNKNOW.toR();
            }
        }
        return save(sysAdminUser)?R.suc():RC.UNKNOW.toR();
    }

    @Override
    public R pageAdminUser(SysAdminUserQueryDto dto) {
        log.debug("SysAdminUserQueryDto:{}",dto);
        IPage<SysAdminUser> userList = page(dto.toPage(),new QueryWrapper<SysAdminUser>());
        return R.suc(userList);
    }

    @Override
    public R getUserAndRoleAndMenus() {
        String userId = StpUtil.getLoginIdAsString();
        SysAdminUser adminUser = getById(userId);
        Map<String,Object> userMap = new HashMap<>();
        userMap.put("userId",userId);
        userMap.put("name",adminUser.getSauName());
        userMap.put("avatar",adminUser.getSauName());
        if(UpmsConstant.SUPER_ADMIN_ID.equals(userId)){
            QueryWrapper<SysAdminRole> userQueryWrapper = Wrappers.query();
            userQueryWrapper.select("role_code");
            List<Object> roles = roleMapper.selectObjs(userQueryWrapper);
            userMap.put("roles",roles);
            QueryWrapper<SysAdminMenu> menuQueryWrapper = Wrappers.query();
            menuQueryWrapper.select("menu_code");
            List<Object> menus = roleMapper.selectObjs(userQueryWrapper);
            userMap.put("menuActions",menus);
        }else{
            List<String> roles = roleMapper.getRolesByUserId(userId);
            userMap.put("roles",roles);
            List<String> menus = menuMapper.getMenuCodesByUser(userId);
            userMap.put("menuActions",menus);
        }
        return R.suc(userMap);
    }

    @Override
    public R getUserNameAndId() {
        List<Map<String,Object>> nameAndIds = list().stream().map(u -> {
            Map<String,Object> nameAndIdMap = new HashMap<>();
            nameAndIdMap.put("id",u.getSauId());
            nameAndIdMap.put("name",u.getSauName());
            return nameAndIdMap;
        }).collect(Collectors.toList());
        return R.suc(nameAndIds);
    }

    @Override
    public R editAdminUser(SysAdminUserDto dto) {
        UpdateWrapper<SysAdminUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("sau_id",dto.getSauId());
        SysAdminUser adminUser = ShunCommonUtils.beanMap(dto,SysAdminUser.class);
        int resultCnt = userMapper.update(adminUser,updateWrapper);
        return (resultCnt>0)? R.suc():R.error(UpmsConstant.EDIT_ADMIN_USR_ERROR);
    }

    @Override
    public R delAdminUserByUserId(String userId) {
        boolean flag = removeById(userId);
        roleMapper.delRolesAndUserByUserId(userId);
        return flag?R.suc():R.error(UpmsConstant.DEL_ADMIN_USR_ERROR);
    }

    /**
     * 根据角色ID获得次角色下的用户列表
     * @return
     */
    public R getUsersByRoleId(String roleId){
        log.debug("roleId:{}",roleId);
        List<SysAdminUser> sysAdminUsers = roleMapper.getUsersByRoleId(roleId);
        List<Map<String,Object>> users = sysAdminUsers.stream().map(s -> {
            Map<String,Object> userMap = new HashMap<>();
            userMap.put("id",s.getSauId());
            userMap.put("name",s.getSauName());
            return userMap;
        }).collect(Collectors.toList());
        return R.suc(users);
    }
}
